//定义一个锻炼协议
//协议包含三个可读属性
protocol Exercise:CustomStringConvertible {
    var name:String{get}
    var caloriesBurned:Double{get}
    var minutes:Double{get}
    var title:String{get}
}

//椭圆机
struct EllipticalWorkout:Exercise {
    let name = "Elliptical Workout"
    let caloriesBurned:Double
    let minutes:Double
    
    var title:String {
        return "\(name) - \(minutes) minutes"
    }
}

let ellipticalWorkout = EllipticalWorkout(caloriesBurned:335,minutes:30)

//跑步机
struct TreadmillWorkout:Exercise {
    let name = "Treadmill Workout"
    let caloriesBurned:Double
    let minutes:Double
    let laps:Double
    
    var title:String {
        return "\(name) - \(minutes) minutes"
    }
    
    //覆盖协议中的默认实现
    //这里的实现优先级更高
    var description:String {
        return "Exercise(\(name),burned \(caloriesBurned) calories and \(laps) in \(minutes) minutes"
    }
}

let runningWorkout = TreadmillWorkout(caloriesBurned:350,minutes:25,laps:10.5)

//计算每分钟消耗多少卡路里
//func caloriesBurnedPerMinute<E:Exercise>(for exercise:E) -> Double {
//    return exercise.caloriesBurned / exercise.minutes
//}

//print(caloriesBurnedPerMinute(for:ellipticalWorkout))
//print(caloriesBurnedPerMinute(for:runningWorkout))

//为协议扩展一个新的属性
extension Exercise {
    var caloriesBurnedPerMinute:Double {
        return caloriesBurned / minutes
    }
}

//所有符合这个协议的类型都可以使用协议扩展中添加的属性和方法
print(ellipticalWorkout.caloriesBurnedPerMinute)
print(runningWorkout.caloriesBurnedPerMinute)


//用协议扩展提供默认实现
extension Exercise {
    var description:String {
        return "Exercise(\(name),burned \(caloriesBurned) calories in \(minutes) minutes"
    }
}

print(ellipticalWorkout)
print(runningWorkout)
//
//extension Exercise {
//    var title:String {
//        return "\(name) - \(minutes) minutes"
//    }
//}
print(ellipticalWorkout.title)
print(runningWorkout.title)
